package com.goldsign.pay.provider.user.service.impl;

import com.goldsign.pay.common.to.accountbase.*;
import com.goldsign.pay.common.to.userbase.*;
import com.goldsign.pay.feign.api.userbase.facade.FeignAccountBaseApi;
import com.goldsign.pay.feign.api.userbase.facade.FeignUserBaseApi;
import com.goldsign.pay.provider.user.dao.UserServiceDao;
import com.goldsign.pay.provider.user.service.UserService;
import com.goldsign.pay.provider.user.to.AccountRegisterReqDTO;
import com.goldsign.pay.provider.user.to.UserLoginReqDTO;
import com.goldsign.pay.provider.user.to.UserServiceResponseDTO;
import com.goldsign.pay.provider.user.vo.AccountRegOrderDO;
import com.goldsign.pay.provider.user.vo.LoginLogDO;
import com.goldsign.pay.provider.user.vo.SmsOrderDO;

import com.goldsign.pay.common.exception.GcServiceException;
import com.goldsign.pay.common.util.Constant;
import com.goldsign.pay.common.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class UserServiceImpl implements UserService {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	private static final String REST_URL_PREFIX = "http://gc-userbase";
	
	@Autowired
	private UserServiceDao userDao;
	@Autowired
	private FeignUserBaseApi feignUserbaseApi;
	@Autowired
	private FeignAccountBaseApi feignAccountBaseApi;

	
	
	@Override
	public void insertAccountRegOrder(AccountRegisterReqDTO req, String orderNo) throws GcServiceException {
		AccountRegOrderDO order = new AccountRegOrderDO();
		order.setTerminal_no(req.getTerminal_no());
		order.setCustomer_ip(req.getCustomer_ip());
		order.setReq_time(req.getReq_time());

		order.setOrder_no(orderNo);
		order.setOrder_status("WAIT");
		
		order.setUser_first_name(req.getUser_first_name());
		order.setUser_last_name(req.getUser_last_name());
		order.setMob_no_country_code(req.getMob_no_country_code());
		order.setMob_no(req.getMob_no());
		order.setEmail(req.getEmail());
		order.setCurrency_type(req.getCurrency_type());
		
		order.setLogin_passwd(req.getLogin_passwd());
		order.setDeal_passwd(req.getDeal_passwd());
		order.setMemo(req.getMemo());
		
		try {
			userDao.insertAccountRegOrder(order);
		} catch (SQLException e) {
			logger.error(req+"_"+ orderNo + "_"+ e.getMessage());
			throw new GcServiceException("DATABASE_ERROR", Constant.DATABASE_ERROR);
		} catch (Exception e) {
			logger.error(req+"_"+ orderNo + "_"+ e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR", Constant.SYSTERM_ERROR);
		}

	}


	@Override
	public boolean checkMobIsRegistered(AccountRegisterReqDTO req) throws GcServiceException {
		GetUserInfoReqDTO getUserInfoReq = new GetUserInfoReqDTO();
		getUserInfoReq.setMob_no(req.getMob_no());
		getUserInfoReq.setMob_no_country_code(req.getMob_no_country_code());

		try {
			GetUserInfoRespDTO getUserInfoResp = feignUserbaseApi.getUserInfoByMobNo(getUserInfoReq);
			if(getUserInfoResp.getResp_code().equals(Constant.MOB_NO_IS_NOT_EXISTS)){
				return false;
			}else {
				return true;
			}

		} catch (Exception e) {
			logger.error(req+"_" + e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR",Constant.SYSTERM_ERROR);
		}

	}

	@Override
	public void insertSmsOrder(AccountRegisterReqDTO req,String busiWaterNo, String smsOrderNo) throws GcServiceException {

		//String verifyCode = getVerifyCode();
		String verifyCode = "123456";

		Date currentTime = new Date();
		String gmtTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(currentTime);
		//验证码有效期10分钟
		String expireTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(
				currentTime.getTime()+ 10 * 60 * 1000);

		SmsOrderDO smsOrder = new SmsOrderDO();

		smsOrder.setTerminal_no(req.getTerminal_no());
		smsOrder.setCustomer_ip(req.getCustomer_ip());
		smsOrder.setReq_time(req.getReq_time());

		smsOrder.setOrder_no(smsOrderNo);
		smsOrder.setOrder_status("0");
		smsOrder.setBusi_water_no(busiWaterNo);

		smsOrder.setMob_no(req.getMob_no());
		smsOrder.setMob_no_country_code(req.getMob_no_country_code());
		smsOrder.setEmail(req.getEmail());
		smsOrder.setSms_type("01");  //账户注册申请
		smsOrder.setVerify_code(verifyCode);
		smsOrder.setExpire_time(expireTime);

		smsOrder.setCheck_error_times(0);

		try {
			userDao.insertSmsOrder(smsOrder);
		} catch (SQLException e) {
			logger.error(req+"_"+ busiWaterNo + "_"+ smsOrderNo + "_"+ e.getMessage());
			throw new GcServiceException("DATABASE_ERROR", Constant.DATABASE_ERROR);
		} catch (Exception e) {
			logger.error(req+"_"+ busiWaterNo + "_"+ smsOrderNo + "_"+ e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR", Constant.SYSTERM_ERROR);
		}
	}


	@Override
	public void sendRegisterMessage() throws GcServiceException {
		// TODO Auto-generated method stub

	}

	@Override
	public AccountRegOrderDO getAccountRegOrderByOrderNo(String orderNo) throws GcServiceException {
		AccountRegOrderDO  accountRegOrder = null;
		try {
			accountRegOrder = userDao.getAccountRegOrderByOrderNo(orderNo);
		} catch (SQLException e) {
			logger.error(orderNo+"_" + e.getMessage());
			throw new GcServiceException("DATABASE_ERROR", Constant.DATABASE_ERROR);
		} catch (Exception e) {
			logger.error(orderNo+"_" + e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR", Constant.SYSTERM_ERROR);
		}
		return accountRegOrder;
	}

	@Override
	public UserServiceResponseDTO validateSmsVerifyCode(String busiWaterNo, String terminalNo,
														String verifyCode, String smsType) throws GcServiceException {
		// TODO Auto-generated method stub
		UserServiceResponseDTO userServiceResponseDTO = new UserServiceResponseDTO();
		try {
			SmsOrderDO smsOrder = new SmsOrderDO();
			smsOrder.setBusi_water_no(busiWaterNo);
			smsOrder.setTerminal_no(terminalNo);
			smsOrder.setSms_type(smsType);

			smsOrder = userDao.getSmsOrderByBusiWaterNo(smsOrder);

			if(smsOrder == null) {
				userServiceResponseDTO.setResp_msg("SMS_ORDER_NOT_EXISTS");
				userServiceResponseDTO.setResp_code(Constant.SMS_ORDER_NOT_EXISTS);
				return userServiceResponseDTO;
			}

			//订单超时，则提示用户重新获取验证
			String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
			if(smsOrder.getExpire_time().compareTo(currentTime) < 0) {
				userServiceResponseDTO.setResp_msg("EXPIRED_VERIFY_CODE");
				userServiceResponseDTO.setResp_code(Constant.EXPIRED_VERIFY_CODE);
				return userServiceResponseDTO;
			}

			//验证码已校验
			if("1".equals(smsOrder.getOrder_status())) {
				userServiceResponseDTO.setResp_msg("CHECKED_VERIFY_CODE");
				userServiceResponseDTO.setResp_code(Constant.CHECKED_VERIFY_CODE);
				return userServiceResponseDTO;
			}

			//累计失败3次，当前验证码失效
			if(smsOrder.getCheck_error_times() >= 3) {
				userServiceResponseDTO.setResp_msg("INVALID_VERIFY_CODE");
				userServiceResponseDTO.setResp_code(Constant.INVALID_VERIFY_CODE);
				return userServiceResponseDTO;
			}

			//成功则更新短信订单状态；失败记录失败次数
			if (!verifyCode.equals(smsOrder.getVerify_code())) {
				userDao.updateSmsOrderForFail(smsOrder.getOrder_no());
				userServiceResponseDTO.setResp_msg("UNCORRECT_VERIFY_CODE");
				userServiceResponseDTO.setResp_code(Constant.UNCORRECT_VERIFY_CODE);
				return userServiceResponseDTO;
			}

			//更新短信订单状态
			userDao.updateSmsOrderForSucc(smsOrder.getOrder_no());
			userServiceResponseDTO.setResp_msg("SUCCESS");
			userServiceResponseDTO.setResp_code(Constant.SUCCESS);
			return userServiceResponseDTO;

		} catch (SQLException e) {
			logger.error(busiWaterNo+ "_" +terminalNo + "_" + verifyCode + "_"+ smsType +"_"+ e.getMessage());
			throw new GcServiceException("DATABASE_ERROR", Constant.DATABASE_ERROR);
		} catch (Exception e) {
			logger.error(busiWaterNo+ "_" +terminalNo + "_" + verifyCode + "_"+ smsType +"_"+ e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR", Constant.SYSTERM_ERROR);
		}
	}

	@Override
	public void updateAccountRegOrder(AccountRegisterReqDTO req) throws GcServiceException {
		AccountRegOrderDO order = new AccountRegOrderDO();
		order.setOrder_no(req.getOrder_no());
		order.setCurrency_type(req.getCurrency_type());
		order.setLogin_passwd(req.getLogin_passwd());
		order.setDeal_passwd(req.getDeal_passwd());

		try {
			int count = userDao.updateAccountRegOrder(order);
			if(count != 1) {
				throw new GcServiceException("REGISTER_ORDER_IS_NOT_EXISTS", Constant.REGISTER_ORDER_IS_NOT_EXISTS);
			}
		} catch (GcServiceException e) {
			throw e;
		} catch (SQLException e) {
			throw new GcServiceException("DATABASE_ERROR", Constant.DATABASE_ERROR);
		} catch (Exception e) {
			throw new GcServiceException("SYSTERM_ERROR", Constant.SYSTERM_ERROR);
		}
	}


	@Override
	public String createUserAccount(AccountRegOrderDO order) throws GcServiceException {
		try {
			//创建用户
			CreateUserReqDTO createUserReq = genCreateUserReq(order);
			CreateUserRespDTO createUserResp = feignUserbaseApi.createUser(createUserReq);

			if (!Constant.SUCCESS.equals(createUserResp.getResp_code() )) {
				throw new GcServiceException(createUserResp.getResp_msg(),createUserResp.getResp_code());
			}

			//用户编号
			String userNo = createUserResp.getUser_no();

			//创建账户
			CreateAccountReqDTO createAccountReq = genCreateAccountReq(order, userNo);
			CreateAccountRespDTO createAccountResp = feignAccountBaseApi.createAccount(createAccountReq);

			if (!Constant.SUCCESS.equals(createAccountResp.getResp_code() )) {
				throw new GcServiceException(createAccountResp.getResp_msg(),createAccountResp.getResp_code());
			}

			return userNo;

		} catch (GcServiceException e) {
			throw e;
		} catch (Exception e) {
			logger.error(order +"_"+ e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR",Constant.SYSTERM_ERROR);
		}
	}

	@Override
	public String insertLoginLog(UserLoginReqDTO req) throws GcServiceException{
		try {
			//获取用户登录信息表的下一个id值
			String id = userDao.getNextLoginLogId();

			LoginLogDO loginLog = new LoginLogDO();

			loginLog.setId(id);
			loginLog.setCustomer_ip(req.getCustomer_ip());
			loginLog.setTerminal_no(req.getTerminal_no());
			loginLog.setReq_time(DateUtil.format("yyyy-MM-dd HH:mm:ss"));

			loginLog.setLogin_id(req.getLogin_id());
			loginLog.setLogin_passwd(req.getLogin_passwd());

			userDao.insertLoginLog(loginLog);

			return id;
		}catch (SQLException e) {
			logger.error(req +"_"+e.getMessage());
			throw new GcServiceException("DATABASE_ERROR", Constant.DATABASE_ERROR);
		} catch (Exception e) {
			logger.error(req +"_"+e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR", Constant.SYSTERM_ERROR);
		}

	}

	@Override
	public void updateLoginLog(String id, String respCode) throws GcServiceException{
		try {
			LoginLogDO loginLogDO = new LoginLogDO();
			loginLogDO.setId(id);
			loginLogDO.setResp_code(respCode);
			userDao.updateLoginLog(loginLogDO);
		}catch (SQLException e) {
			logger.error(id+"_"+respCode+"_"+e.getMessage());
			throw new GcServiceException("DATABASE_ERROR", Constant.DATABASE_ERROR);
		} catch (Exception e) {
			logger.error(id+"_"+respCode+"_"+e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR", Constant.SYSTERM_ERROR);
		}

	}

	@Override
	public String checkLoginPasswd(UserLoginReqDTO req, String id) throws GcServiceException {
		// TODO Auto-generated method stub
		CheckUserLoginPasswdReqDTO checkUserLoginPasswdReq = new CheckUserLoginPasswdReqDTO();
		checkUserLoginPasswdReq.setLogin_id(req.getLogin_id());
		checkUserLoginPasswdReq.setLogin_passwd(req.getLogin_passwd());

		try {
			//调用基础服务，校验登录密码
			CheckUserLoginPasswdRespDTO checkUserLoginPasswdResp = feignUserbaseApi.checkUserLoginPasswd(checkUserLoginPasswdReq);

			if (!Constant.SUCCESS.equals(checkUserLoginPasswdResp.getResp_code())){
				throw new GcServiceException(checkUserLoginPasswdResp.getResp_msg(),
						checkUserLoginPasswdResp.getResp_code());
			}
			return checkUserLoginPasswdResp.getUser_no();
		} catch (GcServiceException e) {
			throw e;
		}  catch (Exception e) {
			logger.error(req+"_"+id+"_" + e.getMessage());
			throw new GcServiceException("SYSTERM_ERROR",Constant.SYSTERM_ERROR);
		}
	}

	private CreateUserReqDTO genCreateUserReq(AccountRegOrderDO order) {
		CreateUserReqDTO req =  new CreateUserReqDTO();
		req.setMob_no(order.getMob_no());
		req.setMob_no_country_code(order.getMob_no_country_code());
		req.setUser_first_name(order.getUser_first_name());
		req.setUser_last_name(order.getUser_last_name());
		req.setLogin_passwd(order.getLogin_passwd());
		req.setDeal_passwd(order.getDeal_passwd());
		req.setTerminal_no(order.getTerminal_no());

		return req;
	}

	private CreateAccountReqDTO genCreateAccountReq(AccountRegOrderDO order, String userNo) {
		CreateAccountReqDTO req = new CreateAccountReqDTO();
		req.setUser_no(userNo);
		req.setCurrency_type(order.getCurrency_type());

		return req;
	}
}
